package com.gitee.exporttool.util;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gitee.exporttool.mapper.ExportMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.io.FilenameUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
public class EasyExcelUtil {

    private static int sheetSize;

    private static int pageSize;

    private static String outFileName;

    public static void writeExcel(ExportMapper exportMapper, String sql) {
        log.info("sheetSize: [{}], pageSize: [{}], outFileName: [{}]", sheetSize, pageSize, outFileName);
        try {
            long total = 0;
            int pageNum = 1;
            int sheetNum = 1;
            IPage<LinkedHashMap<String, Object>> page = exportMapper.selectMap(new Page<>(1, pageSize), sql);
            log.info("sql执行分页结果: 页大小: {}, 当前页:{}, 实际条数: {}, 总页数:{}, 总条数: {}", page.getSize(), page.getCurrent(), page.getRecords().size(), page.getPages(), page.getTotal());
            String fileName = String.format("%s-%s.xlsx", outFileName, LocalDateUtils.dateTimeNow());

            ExcelWriter excelWriter = EasyExcel.write(fileName).head(head(page.getRecords())).build();
            WriteSheet writeSheet = EasyExcel.writerSheet("Sheet1").build();
            excelWriter.write(values(page.getRecords()), writeSheet);
            total += page.getRecords().size();
            do {
                pageNum++;
                page = exportMapper.selectMap(new Page<>(pageNum, pageSize), sql);
                log.info("do-while sql执行分页结果: 当前页已写入条数: {}, 页大小: {}, 当前页: {}, 实际条数: {}, 总页数:{}, 总条数: {}", total, page.getSize(), page.getCurrent(), page.getRecords().size(), page.getPages(), page.getTotal());
                if (sheetSize <= total) {
                    sheetNum++;
                    writeSheet = EasyExcel.writerSheet("Sheet" + sheetNum).build();
                    total = 0;
                }

                if (sheetSize < total + page.getRecords().size()) {
                    log.info("一次查询分页，当前sheet页: {}", writeSheet.getSheetName());
                    excelWriter.write(values(page.getRecords()).subList(0, (int) (sheetSize - total)), writeSheet);
                    log.info("do-while 当前页已写入: {}条, 需要分页写. 当前页写入了: {}", sheetSize, sheetSize - total);
                    sheetNum++;
                    writeSheet = EasyExcel.writerSheet("Sheet" + sheetNum).build();
                    log.info("一次查询分页，当前sheet页: {}", writeSheet.getSheetName());
                    excelWriter.write(values(page.getRecords()).subList((int) (sheetSize - total), page.getRecords().size()), writeSheet);
                    total = page.getRecords().size() - sheetSize + total;
                } else {
                    log.info("当前sheet页: {}", writeSheet.getSheetName());
                    excelWriter.write(values(page.getRecords()), writeSheet);
                    total += page.getRecords().size();
                }
            } while (pageNum < page.getPages());
            excelWriter.finish();
            log.info("写[{}}文件结束", fileName);
        } catch (Exception e) {
            log.error("写文件失败", e);
        }
    }

    public static void writeExcel(List<LinkedHashMap<String, Object>> data, String buildDir) {
        log.info("开始写入excel文件 data size {}", data.size());
        if (CollectionUtils.isEmpty(data)) {
            return;
        }
        String fileName = FilenameUtils.concat(buildDir, "test.xlsx");
        List<List<String>> headList = head(data);
        EasyExcel.write(fileName)
            .head(headList)
            .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
            .sheet("Sheet1").doWrite(values(data));
    }

    private static List<List<String>> head(List<LinkedHashMap<String, Object>> data) {
        if (CollectionUtils.isNotEmpty(data)) {
            return data.get(0).keySet().stream().map(k -> Arrays.asList(k)).collect(Collectors.toList());
        }

        return null;
    }

    private static List<List<Object>> values(List<LinkedHashMap<String, Object>> data) {
        if (CollectionUtils.isNotEmpty(data)) {
            return data.stream().map(m -> new ArrayList<>(m.values())).collect(Collectors.toList());
        }

        return null;
    }

    public static void setPageSize(int pageSize) {
        EasyExcelUtil.pageSize = pageSize;
    }

    public static void setFileName(String outFileName) {
        EasyExcelUtil.outFileName =  outFileName;
    }

    public static void setSheetSize(int sheetSize) {
        EasyExcelUtil.sheetSize = sheetSize;
    }
}
